package com.xiaoq.shop.endpoint;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xiaoq.BaseEndpoint2B;
import com.xiaoq.apis.sites.ISitesApi;
import com.xiaoq.apis.sites.SitesInfo4SocialVo;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.order.entity.ShopOrderEntity;
import com.xiaoq.order.service.IShopOrderService;
import com.xiaoq.schedule.order.IOrderScheduleApi;
import com.xiaoq.shop.entity.CouponEntity;
import com.xiaoq.shop.entity.SimpleLock;
import com.xiaoq.shop.entity.UserCouponEntity;
import com.xiaoq.shop.service.ICouponService;
import com.xiaoq.shop.service.ISimpleLockService;
import com.xiaoq.shop.service.IUserCouponService;
import com.xiaoq.shop.vo.AddCouponVO;
import com.xiaoq.shop.vo.Coupon4BVo;
import com.xiaoq.shop.vo.CouponVO;
import com.xiaoq.vo.PagingVo;
import io.swagger.annotations.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.groupingBy;


@RestController
@RequestMapping(value = "/api/v1/coupons")
@Api(tags={"优惠券管理Api"})
public class CouponEndpoint2B extends BaseEndpoint2B{

    private static final class CouponResponse extends GenericDataResponse<CouponVO> {}
    private static final class Coupon4BVoResponse extends GenericListResponse<Coupon4BVo> {}

    @Autowired
    private ICouponService couponService;

    @Autowired
    private ISimpleLockService simpleLockService;

    @Reference(interfaceClass=ISitesApi.class, check=false, version="1.0.0")
    private ISitesApi sitesApi;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private IUserCouponService userCouponService;

    @Autowired
    private IShopOrderService shopOrderService;

    @Reference(interfaceClass=IOrderScheduleApi.class, check=false, version="1.0.0")
    private IOrderScheduleApi orderScheduleApi;


    @ApiOperation(value="查询优惠券列表", notes="查询优惠券列表")
    @ApiResponses({
            @ApiResponse(code = 200, response = Coupon4BVoResponse.class, message = "查询优惠券列表")
    })
    @GetMapping(value="/list", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> couponList(HttpServletRequest request,
                                        @RequestParam("type") @ApiParam(name = "type", value="all(全部),wait(未开始),start(进行中开始),end(已结束)", required=true) String type,
                                        @ApiParam(value="pn", required=false) @RequestParam(required = false, defaultValue = "1") int pn,
                                        @ApiParam(value="ps", required=false) @RequestParam(required = false, defaultValue = "10") int ps) {

        String userId = (String) request.getAttribute("userId");
        String shopId = getShopId();
        PagingVo pagingVo = new PagingVo(pn, ps);
        List<Coupon4BVo> couponVOList = new ArrayList<>();
        List<CouponEntity> couponList = couponService.getAllCouponList(shopId, type, pagingVo);
        long totalCount = couponService.getAllCouponListCount(shopId, type);

        List<String> couponInstanceCodeList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(couponList)){
            for (CouponEntity couponEntity : couponList){
                couponInstanceCodeList.add(couponEntity.getId());
                Coupon4BVo coupon4BVo = new Coupon4BVo();
                BeanUtils.copyProperties(couponEntity, coupon4BVo);
                couponVOList.add(coupon4BVo);
            }

            List<UserCouponEntity> userCouponList = userCouponService.getUserCouponList(shopId, couponInstanceCodeList);
            userCouponList = userCouponList==null ? new ArrayList<>() : userCouponList;
            Map<String, List<UserCouponEntity>> couponId2CouponListMap = userCouponList.stream().collect(groupingBy(UserCouponEntity::getCouponInstanceCode));

            List<ShopOrderEntity> orderEntityList = shopOrderService.getShopOrderList(shopId, couponInstanceCodeList);
            orderEntityList = orderEntityList == null ? new ArrayList<>() : orderEntityList;
            Map<String, List<ShopOrderEntity>> couponId2OrderListMap = orderEntityList.stream().collect(groupingBy(ShopOrderEntity::getCouponCode));

            for(Coupon4BVo coupon4BVo : couponVOList){
                String couponId = coupon4BVo.getId();

                if(couponId2OrderListMap.containsKey(couponId)){
                    List<ShopOrderEntity> shopOrderEntityList = couponId2OrderListMap.get(couponId);
                    coupon4BVo.setHasUse(shopOrderEntityList==null?0:shopOrderEntityList.size());
                }

                if(couponId2CouponListMap.containsKey(couponId)){
                    List<UserCouponEntity> userCouponEntityList = couponId2CouponListMap.get(couponId);
                    if(userCouponEntityList == null){
                        coupon4BVo.setPeopleTakenCount(0);
                    }else{
                        coupon4BVo.setPeopleTakenCount(userCouponEntityList.stream().collect(groupingBy(UserCouponEntity::getUserId)).size());
                    }
                }
            }
        }

        return Coupon4BVoResponse.listAndCount(couponVOList, totalCount);
    }

    @ApiOperation(value="添加优惠券", notes="添加优惠券")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "添加优惠券")
    })
    @PostMapping(value="", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> addCoupon(HttpServletRequest request,
                                       @ModelAttribute AddCouponVO couponVO) {

        if(couponVO == null){
            return GenericResponse.ng("请求体不能为空");
        }

        String shopId = getShopId();

        if(StringUtils.isBlank(shopId)){
            return GenericResponse.ng("未获取到登录用户的店ID,请重新登录");
        }

        SitesInfo4SocialVo siteInfo4Social = sitesApi.getSiteInfo4Social(shopId);
        if(siteInfo4Social==null || StringUtils.isEmpty(siteInfo4Social.getName())){
            return GenericResponse.ng("未获取到登录用户的店名称,请重新登录");
        }
        String shopName = siteInfo4Social.getName();

        CouponEntity couponEntity = new CouponEntity();
        BeanUtils.copyProperties(couponVO, couponEntity);
        couponEntity.setId(idGenerator.nextId());
        couponEntity.setShopId(shopId);
        couponEntity.setShopName(shopName);
        couponEntity.setState(ConstantUtil.COUPON_SALE_ON);  //在C端显示
        couponEntity.setCouponTemplateCode((long)(Math.random() * 1000));
        couponEntity.setExtension("2"); // （优惠券领取方式） 2: 卖家发放

        boolean successFlag = couponService.save(couponEntity);
        if(successFlag){
            SimpleLock simpleLock = new SimpleLock();
            simpleLock.setId(idGenerator.nextId());
            simpleLock.setTargetId(couponEntity.getId());
            simpleLock.setLockStatus(0);
            simpleLockService.save(simpleLock);
            return GenericResponse.ok();
        }

        return GenericResponse.ng("添加优惠券失败");
    }

    @ApiOperation(value="修改优惠券", notes="修改优惠券")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "修改优惠券")
    })
    @PutMapping(value="/{couponId}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> updateCoupon(HttpServletRequest request,
                                       @ModelAttribute AddCouponVO couponVO,
                                          @PathVariable @ApiParam(value="优惠券ID", required=true) String couponId) {

        if(couponVO==null || StringUtils.isBlank(couponId)){
            return GenericResponse.ng("请求体不能为空");
        }

        String shopId = getShopId();
        if(StringUtils.isEmpty(shopId)){
            return GenericResponse.ng("未获取到用户的店ID信息");
        }

        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setShopId(shopId);
        BeanUtils.copyProperties(couponVO, couponEntity);
        couponEntity.setId(couponId);

        boolean successFlag = couponService.updateById(couponEntity);
        if(successFlag){
            return GenericResponse.ok();
        }
        logger.error("修改优惠券失败, shopId: " + shopId);
        return GenericResponse.ng("修改优惠券失败");
    }

    @ApiOperation(value="修改优惠券，使失效", notes="修改优惠券，使失效")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "修改优惠券，使失效")
    })
    @PutMapping(value="/{couponId}/toinvalid", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> toInvalid(HttpServletRequest request,
                                          @PathVariable @ApiParam(value="优惠券ID", required=true) String couponId) {

        String shopId = getShopId();
        if(StringUtils.isEmpty(shopId)){
            return GenericResponse.ng("未获取到用户的店信息");
        }
        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setId(couponId);
        couponEntity.setState(ConstantUtil.SALE_STATE_OFF); //即在C端不显示
        couponEntity.setId(couponId);
        couponEntity.setShopId(shopId);

        boolean successFlag = couponService.updateById(couponEntity);
        if(successFlag){
            return GenericResponse.ok();
        }

        return GenericResponse.ng("修改优惠券失效失败");
    }

    @ApiOperation(value="得到某一条优惠券信息", notes="得到某一条优惠券信息")
    @ApiResponses({
            @ApiResponse(code = 200, response = CouponResponse.class, message = "得到某一条优惠券信息")
    })
    @GetMapping(value="/{couponId}/info", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> getCoupon(HttpServletRequest request,
                                       @PathVariable @ApiParam(value="优惠券ID", required=true) String couponId) {

        String shopId = getShopId();

        if(StringUtils.isBlank(shopId)){
            return GenericResponse.ng("未获取到登录用户的店ID,请重新登录");
        }
        CouponEntity couponEntity = couponService.getCouponById(couponId);
        if(couponId==null || StringUtils.isBlank(couponEntity.getId())){
            return GenericResponse.ng("ID为" + couponId + "的优惠券不存在");
        }
        if(!shopId.equals(couponEntity.getShopId())){
            return GenericResponse.ng("此优惠券不是[" + shopId + "]公司的优惠券");
        }

        CouponVO couponVO = new CouponVO();
        BeanUtils.copyProperties(couponEntity, couponVO);

        return CouponResponse.okWithData(couponVO);
    }


    @ApiOperation(value="根据优惠券标题搜索优惠券", notes="根据优惠券标题搜索优惠券")
    @ApiResponses({
            @ApiResponse(code = 200, response = Coupon4BVoResponse.class, message = "根据优惠券标题搜索优惠券")
    })
    @GetMapping(value="/list/search", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> getCouponListFromEs(HttpServletRequest request,
                                                 @ApiParam(value="优惠券标题", required=true) @RequestParam(value = "title",required = true) String title,
                                                 @ApiParam(value="页码,从1开始", required=false) @RequestParam(defaultValue = "1") int pn,
                                                 @ApiParam(value="条数", required=false) @RequestParam(defaultValue = "10") int ps) {

        String shopId = getShopId();
        PagingVo pagingVo = new PagingVo(pn-1, ps);

        List<Coupon4BVo> couponVOList = new ArrayList<>();
        List<CouponEntity> couponList = couponService.getCouponListFromEs(shopId, title, pagingVo);

        List<String> couponInstanceCodeList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(couponList)) {
            for (CouponEntity couponEntity : couponList) {
                couponInstanceCodeList.add(couponEntity.getId());
                Coupon4BVo coupon4BVo = new Coupon4BVo();
                BeanUtils.copyProperties(couponEntity, coupon4BVo);
                couponVOList.add(coupon4BVo);
            }
        }

        return Coupon4BVoResponse.listNoCount(couponVOList);
    }



    @ApiOperation(value="推送测试", notes="推送测试")
    @ApiResponses({
            @ApiResponse(code = 200, response = GenericResponse.class, message = "推送测试")
    })
    @GetMapping(value="/push", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> pushTest() {

        orderScheduleApi.pushCouponMessage4QuickExpired();

        return GenericResponse.ok();
    }


}
